Fix PCI iomem resource fixup.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 5 Sep 2005 19:53:44 +0000 (19:53 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 5 Sep 2005 19:53:44 +0000 (19:53 +0000)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c
xen/arch/x86/dom0_ops.c
xen/common/domain.c
xen/common/memory.c
xen/include/public/dom0_ops.h

index 1cbe2bb77eb2261122f3fda7b334f4f770cbe120..611cd676950a5f385064c024afa9201cda9afad9 100644 (file)
@@ -1235,10 +1235,64 @@ static void __init
 legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
 {
        int i;
+#ifdef CONFIG_XEN
+       dom0_op_t op;
+       struct dom0_memory_map_entry *map;
+       unsigned long gapstart, gapsize;
+       unsigned long long last;
+#endif
 
 #ifdef CONFIG_XEN_PRIVILEGED_GUEST
        probe_roms();
 #endif
+
+#ifdef CONFIG_XEN
+       map = alloc_bootmem_low_pages(PAGE_SIZE);
+       op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
+       op.u.physical_memory_map.memory_map = map;
+       op.u.physical_memory_map.max_map_entries =
+               PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
+       BUG_ON(HYPERVISOR_dom0_op(&op));
+
+       last = 0x100000000ULL;
+       gapstart = 0x10000000;
+       gapsize = 0x400000;
+
+       for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
+               struct resource *res;
+
+               if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
+                       gapsize = last - map[i].end;
+                       gapstart = map[i].end;
+               }
+               if (map[i].start < last)
+                       last = map[i].start;
+
+               if (map[i].end > 0x100000000ULL)
+                       continue;
+               res = alloc_bootmem_low(sizeof(struct resource));
+               res->name = map[i].is_ram ? "System RAM" : "reserved";
+               res->start = map[i].start;
+               res->end = map[i].end - 1;
+               res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+               request_resource(&iomem_resource, res);
+       }
+
+       free_bootmem(__pa(map), PAGE_SIZE);
+
+       /*
+        * Start allocating dynamic PCI memory a bit into the gap,
+        * aligned up to the nearest megabyte.
+        *
+        * Question: should we try to pad it up a bit (do something
+        * like " + (gapsize >> 3)" in there too?). We now have the
+        * technology.
+        */
+       pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+       printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
+               pci_mem_start, gapstart, gapsize);
+#else
        for (i = 0; i < e820.nr_map; i++) {
                struct resource *res;
                if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
@@ -1264,6 +1318,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                        request_resource(res, data_resource);
                }
        }
+#endif
 }
 
 /*
@@ -1271,23 +1326,29 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
  */
 static void __init register_memory(void)
 {
+#ifndef CONFIG_XEN
        unsigned long gapstart, gapsize;
        unsigned long long last;
+#endif
        int           i;
 
+       /* Nothing to do if not running in dom0. */
+       if (!(xen_start_info->flags & SIF_INITDOMAIN))
+               return;
+
        if (efi_enabled)
                efi_initialize_iomem_resources(&code_resource, &data_resource);
        else
                legacy_init_iomem_resources(&code_resource, &data_resource);
 
-       if (xen_start_info->flags & SIF_INITDOMAIN)
-               /* EFI systems may still have VGA */
-               request_resource(&iomem_resource, &video_ram_resource);
+       /* EFI systems may still have VGA */
+       request_resource(&iomem_resource, &video_ram_resource);
 
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < STANDARD_IO_RESOURCES; i++)
                request_resource(&ioport_resource, &standard_io_resources[i]);
 
+#ifndef CONFIG_XEN
        /*
         * Search for the bigest gap in the low 32 bits of the e820
         * memory space.
@@ -1328,6 +1389,7 @@ static void __init register_memory(void)
 
        printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
                pci_mem_start, gapstart, gapsize);
+#endif
 }
 
 /* Use inline assembly to define this because the nops are defined 
index 8ca939aef1500ba2644441090d7c79e638e592ec..c891371b28d4a1a2726575675134c1ed0809328f 100644 (file)
@@ -517,11 +517,10 @@ void __init setup_memory_region(void)
 }
 
 #else  /* CONFIX_XEN */
+
 extern unsigned long xen_override_max_pfn;
 extern union xen_start_info_union xen_start_info_union;
-/*
- * Guest physical starts from 0.
- */
+
 unsigned long __init e820_end_of_ram(void)
 {
         unsigned long max_end_pfn = xen_start_info->nr_pages;
@@ -532,11 +531,69 @@ unsigned long __init e820_end_of_ram(void)
         return xen_override_max_pfn;
 }
 
-
-
 void __init e820_reserve_resources(void) 
 {
-       return;                 /* Xen won't have reserved entries */
+       dom0_op_t op;
+       struct dom0_memory_map_entry *map;
+       unsigned long gapstart, gapsize, last;
+       int i, found = 0;
+
+       if (!(xen_start_info->flags & SIF_INITDOMAIN))
+               return;
+
+       map = alloc_bootmem_low_pages(PAGE_SIZE);
+       op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
+       op.u.physical_memory_map.memory_map = map;
+       op.u.physical_memory_map.max_map_entries =
+               PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
+       BUG_ON(HYPERVISOR_dom0_op(&op));
+
+       last = 0x100000000ULL;
+       gapstart = 0x10000000;
+       gapsize = 0x400000;
+
+       for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
+               struct resource *res;
+
+               if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
+                       gapsize = last - map[i].end;
+                       gapstart = map[i].end;
+                       found = 1;
+               }
+               if (map[i].start < last)
+                       last = map[i].start;
+
+               if (map[i].end > 0x100000000ULL)
+                       continue;
+               res = alloc_bootmem_low(sizeof(struct resource));
+               res->name = map[i].is_ram ? "System RAM" : "reserved";
+               res->start = map[i].start;
+               res->end = map[i].end - 1;
+               res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+               request_resource(&iomem_resource, res);
+       }
+
+       free_bootmem(__pa(map), PAGE_SIZE);
+
+       if (!found) {
+               HYPERVISOR_memory_op(XENMEM_maximum_ram_page, &gapstart);
+               gapstart = (gapstart << PAGE_SHIFT) + 1024*1024;
+               printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
+                      KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
+       }
+
+       /*
+        * Start allocating dynamic PCI memory a bit into the gap,
+        * aligned up to the nearest megabyte.
+        *
+        * Question: should we try to pad it up a bit (do something
+        * like " + (gapsize >> 3)" in there too?). We now have the
+        * technology.
+        */
+       pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+       printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
+               pci_mem_start, gapstart, gapsize);
 }
 
 #endif
@@ -558,6 +615,7 @@ unsigned long pci_mem_start = 0xaeedbabe;
  */
 __init void e820_setup_gap(void)
 {
+#ifndef CONFIG_XEN
        unsigned long gapstart, gapsize;
        unsigned long last;
        int i;
@@ -606,4 +664,5 @@ __init void e820_setup_gap(void)
 
        printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
                pci_mem_start, gapstart, gapsize);
+#endif
 }
index 01ea09b74e7c0352a50b61270a024ccbdd0ff411..06562059c406b2fbf07966997042424601585420 100644 (file)
@@ -389,9 +389,31 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
     }
     break;
 
+    case DOM0_PHYSICAL_MEMORY_MAP:
+    {
+        struct dom0_memory_map_entry entry;
+        int i;
+
+        for ( i = 0; i < e820.nr_map; i++ )
+        {
+            if ( i >= op->u.physical_memory_map.max_map_entries )
+                break;
+            entry.start  = e820.map[i].addr;
+            entry.end    = e820.map[i].addr + e820.map[i].size;
+            entry.is_ram = (e820.map[i].type == E820_RAM);
+            (void)copy_to_user(
+                &op->u.physical_memory_map.memory_map[i],
+                &entry, sizeof(entry));
+        }
+
+        op->u.physical_memory_map.nr_map_entries = i;
+        (void)copy_to_user(u_dom0_op, op, sizeof(*op));
+    }
+    break;
+
     default:
         ret = -ENOSYS;
-
+        break;
     }
 
     return ret;
index a5460759d643f8ac1138994595132e57fdd18401..eaea4bcc9dc738e7881463b20b9ec6adb8c43569 100644 (file)
@@ -176,10 +176,7 @@ __initcall(domain_shutdown_finaliser_init);
 void domain_shutdown(u8 reason)
 {
     struct domain *d = current->domain;
-    struct vcpu *v;
-
-    if(reason == SHUTDOWN_crash) 
-        printk("Domain %d crash detected.\n", d->domain_id); 
+    struct vcpu   *v;
 
     if ( d->domain_id == 0 )
     {
index c1019c9dbad5f5f394bf2f8086050d781037417f..ca394edb810968f7d42e2b5866da115bfffc6a1e 100644 (file)
@@ -190,7 +190,7 @@ long do_memory_op(int cmd, void *arg)
     case XENMEM_maximum_ram_page:
         if ( put_user(max_page, (unsigned long *)arg) )
             return -EFAULT;
-        rc = -ENOSYS;
+        rc = 0;
         break;
 
     default:
index b8928b0f6875477986ad6ff7f80e550fde632224..508ba6779aba51e4df9c6792de7e43e8f5a3e1ab 100644 (file)
@@ -374,6 +374,18 @@ typedef struct {
     int quirk_id;
 } dom0_platform_quirk_t;
 
+#define DOM0_PHYSICAL_MEMORY_MAP 40
+typedef struct {
+    /* IN variables. */
+    int max_map_entries;
+    /* OUT variables. */
+    int nr_map_entries;
+    struct dom0_memory_map_entry {
+        u64 start, end;
+        int is_ram;
+    } *memory_map;
+} dom0_physical_memory_map_t;
+
 typedef struct {
     u32 cmd;
     u32 interface_version; /* DOM0_INTERFACE_VERSION */
@@ -408,6 +420,7 @@ typedef struct {
         dom0_getvcpucontext_t    getvcpucontext;
         dom0_getdomaininfolist_t getdomaininfolist;
         dom0_platform_quirk_t    platform_quirk;
+        dom0_physical_memory_map_t physical_memory_map;
     } u;
 } dom0_op_t;